// 封装uni请求变成Promise风格
import { useUserInfoStore } from "@/stores/userInfo";
const userInfoStore = useUserInfoStore();
import { getToken } from "@/api/index";

interface IConfig {
  baseUrl: string;
  timeout?: number;
  header?: any;
}

interface IOptions {
  url: string;
  headers?: any;
  method?: "GET" | "POST" | "DELETE" | "PUT";
  data?: any;
}

interface IUploadOptions {
  url: string;
  headers?: any;
  method?: "GET" | "POST" | "DELETE" | "PUT";
  data: {
    name: string;
    filePath: any;
  };
}

interface IReturnRes {
  code: number;
  data?: any;
  msg: string;
  success: boolean;
  error: boolean;
}
export default class Request {
  private baseUrl: string;
  private timeout: number;
  private header: any;

  constructor(config: IConfig) {
    this.baseUrl = config.baseUrl;
    this.timeout = config.timeout || 8000;
    this.header = config.header || {};
  }
  _request(options: IOptions): Promise<IReturnRes> {
    // 请求白名单
    const whiteUrls = [
      "/wx-login/getWxOpenId",
      "/wx-login/wxLogin",
      "/anti-fraud/listPage", //反诈宣传列表
      "/anti-fraud/selectOne", //反诈宣传详情
      "/firefighting/listPage", //消防安全列表
      "/firefighting/selectOne", //消防安全详情
      "/preventive/listPage", //防范提示列表
      "/preventive/selectOne", //防范提示详情
      "/community/selectAll",
      "/loginTest",
      "/wx-login/getCommunityByPoint",
      "/affairs-guide/listPage", //办事指南首页列表
      "/affairs-guide/selectOne", //办事指南详情
      "/affairs-guide/clickHandle", //办事指南浏览量
      "/affairs-guide/listGroup", //办事指南列表
      "/affairs-guide/search", //办事指南搜索
    ];
    // 全局的请求拦截器
    uni.addInterceptor("request", {
      invoke(args) {
        // 在发起请求前做的事情
        if (!whiteUrls.find((item) => item == options.url)) {
          args.header = {
            // 请求头带token
            Authorization: "Bearer " + userInfoStore.token,
          };
        }
      },
      success(res) {
        // console.log(res);
      },
      fail(err) {
        console.log(err);
      },
    });

    return new Promise((resolve, reject) => {
      uni.request({
        url: this.baseUrl + options.url,
        timeout: this.timeout,
        header: {
          ...this.header,
          ...options.headers, // 可以请求时传自定义请求头
        },
        method: options.method || "GET",
        data: options.data,
        success: (res: any) => {
          const data: IReturnRes = res.data;
          if (data.code == 200) {
            resolve(data);
          } else if (data.code === 401) {
            getToken({
              userId: userInfoStore.userInfo.userId,
              userType: userInfoStore.userInfo.userType,
            })
              .then((res) => {
                const { data } = res;
                userInfoStore.setToken(data);
                this._request(options);
              })
              .catch((err) => {
                uni.$u.toast(err);
              });
          } else {
            reject(data.msg);
          }
        },
        fail: (err: any) => {
          uni.$u.toast(this.baseUrl + options.url);
          uni.showToast({
            title: "请求失败",
            icon: "error",
          });
          // reject(err);
        },
        complete: () => {},
      });
    });
  }

  get(options: IOptions): Promise<IReturnRes> {
    return this._request({
      ...options,
    });
  }

  post(options: IOptions): Promise<IReturnRes> {
    return this._request({
      ...options,
      method: "POST",
    });
  }

  put(options: IOptions): Promise<IReturnRes> {
    return this._request({
      ...options,
      method: "PUT",
    });
  }

  del(options: IOptions): Promise<IReturnRes> {
    return this._request({
      ...options,
      method: "DELETE",
    });
  }

  // 上传文件
  upload(options: IUploadOptions): Promise<IReturnRes> {
    uni.showLoading({
      title: "上传中",
    });
    return new Promise((resolve, reject) => {
      uni.uploadFile({
        url: this.baseUrl + options.url,
        header: {
          // 请求头带token
          "Authori-zation": "Bearer " + userInfoStore.token,
          ...options.headers,
        },
        filePath: options.data.filePath,
        name: options.data.name,
        formData: {
          filename: options.data.name,
        },
        success: (res: any) => {
          const data: IReturnRes = res.data;
          if (data.code == 200) {
            resolve(data);
          } else if (data.code === 401) {
            uni.$u.toast("登录状态已过期，请重新登录");
            // pinia.login();
          } else {
            reject(data.msg);
          }
        },
        fail: (err: any) => {
          uni.hideLoading();
          uni.showToast({
            title: "请求失败",
            icon: "error",
          });
          // reject(err);
        },
      });
    });
  }
}
